package com.nowcoder.community.controller;

import com.nowcoder.community.annotation.LoginRequired;
import com.nowcoder.community.pojo.User;
import com.nowcoder.community.service.FollowService;
import com.nowcoder.community.service.LikeService;
import com.nowcoder.community.service.UserService;
import com.nowcoder.community.util.CommunityConstant;
import com.nowcoder.community.util.CommunityUtil;
import com.nowcoder.community.util.HostHolder;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Map;

@Api(description = "用户相关")
@Controller
@RequestMapping("/user")
public class UserController implements CommunityConstant{

    public static final Logger logger = LoggerFactory.getLogger(UserController.class);

    @Value("${community.path.upload}")
    private String uploadPath;

    @Value("${community.path.domain}")
    private String domain;

    @Value("${server.servlet.context-path}")
    private String contextPath;

    @Autowired
    @Qualifier("userService")
    private UserService userService;

    @Autowired
    @Qualifier("likeService")
    private LikeService likeService;

    @Autowired
    @Qualifier("followService")
    private FollowService followService;

    @Autowired
    private HostHolder hostHolder;

    @Value("${qiniu.key.access}")
    private String accessKey;

    @Value("${qiniu.key.secret}")
    private String secretKey;

    @Value("${qiniu.bucket.header.name}")
    private String headerBucketName;

    @Value("${qiniu.bucket.header.url}")
    private String headerBucketUrl;

    //进入修改个人信息的页面
//    @LoginRequired
    @ApiOperation(value = "跳转到个人信息页面（跳转时需要上传登录凭证）")
    @GetMapping("/setting")
    public String getSettingPage(Model model){
//        System.out.println("进入了setting---------------------");
        String fileName = CommunityUtil.generateUUID();//生成文件名
        //设置响应信息
        StringMap policy = new StringMap();
        policy.put("returnBody", CommunityUtil.getJSONString(0));

        //生成上传凭证（仅仅是生成上传凭证）
        Auth auth = Auth.create(accessKey, secretKey);
        //参数1：存储空间   参数2：文件名   参数3：key的有效时间   参数4：凭证
        String uploadToken = auth.uploadToken(headerBucketName, fileName, 3600, policy);

        model.addAttribute("uploadToken", uploadToken);
        model.addAttribute("fileName", fileName);
//        System.out.println("退出了setting---------------------");

        return "site/setting";
    }

    @ApiOperation(value = "更新用户头像")
    @PostMapping("/header/url")
    @ResponseBody
    public String updateHeaderUrl(String fileName) {
//        System.out.println("进入了updateHeaderUrl---------------------");
        if(StringUtils.isBlank(fileName)){
            return CommunityUtil.getJSONString(1, "文件名不能为空！");
        }

        String url = headerBucketUrl + "/" + fileName;

        userService.updateHeader(hostHolder.getUser().getId(), url);
//        System.out.println("退出了updateHeaderUrl---------------------");

        return CommunityUtil.getJSONString(0);
    }
    //上传头像（已废弃）
//    @LoginRequired
    @ApiOperation(value = "加载用户头像图片（已废弃）")
    @PostMapping("/upload")
    public String uploadHeader(MultipartFile headerImage, Model model){
        if (headerImage == null){
            model.addAttribute("error", "您还没有选择图片！");
            return "/site/setting";
        }
        //获取原始文件名
        String filename = headerImage.getOriginalFilename();

        //获取文件名后缀
        String suffix = filename.substring(filename.lastIndexOf("."));

        if (StringUtils.isBlank(suffix)){
            model.addAttribute("error", "文件格式不正确！");
            return "/site/setting";
        }

        //生成随机文件名
        filename = CommunityUtil.generateUUID() + suffix;

        //确定文件存放的路径
        File fileDest = new File(uploadPath + "/" + filename);

        try {
            //向这个路径存储文件
            headerImage.transferTo(fileDest);
        } catch (IOException e) {
            logger.error("文件上传失败：" + e.getMessage());
            throw new RuntimeException("文件上传失败，服务器发生异常！", e);
        }


        //获取当前用户
        User user = hostHolder.getUser();

        //获取当前用户头像的路径（web访问路径）
        //http://localhost:8080/community/user/header/xxx.png
        String headerUrl = domain + contextPath + "/user/header/" + suffix;

        //更新当前用户的头像（更新的是获取头像的路径，如果在页面中这个路径发生变化，那么头像就会改变）
        userService.updateHeader(user.getId(), headerUrl);

        return "redirect:/index";
    }

    //这里接收的请求就是获取用户头像的web访问路径headerUrl，这里fileName的接收数据就是上面方法中的suffix
    //已废弃
    @ApiOperation(value = "获取用户头像图片（已废弃）")
    @GetMapping("/header/{fileName}")
    public void getHeader(@PathVariable("fileName") String fileName, HttpServletResponse response){
        //服务器存放路径
        fileName = uploadPath + "/" + fileName;
        
        //获取文件名后缀
        String suffix = fileName.substring(fileName.lastIndexOf("."));

        //将图片响应到页面中。setContentType：设置请求以及响应的内容类型以及编码方式
        response.setContentType("image/" + suffix);


        //使用try... with resource语句，io流使用后自动关闭，无须手动
        try (
                FileInputStream fis = new FileInputStream(fileName)
        ){
            ServletOutputStream os = response.getOutputStream();
            byte[] b = new byte[1024];
            int len = 0;

            while ((len = fis.read(b)) != -1)
                os.write(b, 0, len);

        } catch (IOException e) {
            logger.error("获取头像失败：" + e.getMessage());
            e.printStackTrace();
        }

    }
    /*总体来说，获取头像是先往某个路径中存图片，在访问这个路径来获取图片*/

    @ApiOperation(value = "更新密码")
    @PostMapping("/updatePwd")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "oldPassword", value = "原始密码"),
            @ApiImplicitParam(name = "newPassword", value = "新密码"),
            @ApiImplicitParam(name = "rePassword", value = "确认密码")
    })
    public String updatePassword(Model model,
                                 @RequestParam("oldPassword") String oldPassword,
                                 @RequestParam("newPassword") String newPassword,
                                 @RequestParam("rePassword") String rePassword){

        Map<String, Object> map = userService.updatePassword(oldPassword, newPassword, rePassword);

        if (map == null || map.isEmpty()){
//            System.out.println("---------->修改成功");
            return "redirect:/login";
        } else{
//            System.out.println("---------->修改失败");
            model.addAttribute("oldPwdMsg", map.get("oldPwdMsg"));
            model.addAttribute("newPwdMsg", map.get("newPwdMsg"));
            model.addAttribute("pwdMsgDiff", map.get("pwdMsgDiff"));

            return "site/setting";//此处不能重定向，重定向时就是两个不同的请求，model只在当前请求有效
        }

    }

    //个人主页信息
    @ApiOperation(value = "个人主页信息")
    @GetMapping("/profile/{userId}")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id")
    })
    public String getProfilePage(@PathVariable("userId") int userId, Model model){

        User user = userService.findUserById(userId);

        if (user == null){
            throw new RuntimeException("该用户不存在！");
        }

        //用户
        model.addAttribute("user", user);

        //点赞数量
        int likeCount = likeService.findUserLikeCount(userId);
        model.addAttribute("likeCount", likeCount);

        //关注数量
        long followeeCount = followService.findFolloweeCount(userId, ENTITY_TYPE_USER);
        model.addAttribute("followeeCount", followeeCount);

        //粉丝数量
        long followerCount = followService.findFollowerCount(ENTITY_TYPE_USER, userId);
        model.addAttribute("followerCount", followerCount);

        //是否已关注
        boolean hasFollowed = false;
        if (hostHolder.getUser() != null){
            hasFollowed = followService.hasFollowed(hostHolder.getUser().getId(),
                    ENTITY_TYPE_USER, userId);
        }

        model.addAttribute("hasFollowed", hasFollowed);

        return "site/profile";
    }

}
